package com.duguo.dynamicmvc.factory.utils.javassist;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;

import com.duguo.dynamicmvc.factory.utils.BeanUtils;


public class FieldUtils {


    public static void setupField(CtClass targetCtClass, CtClass fieldCtClass, String fieldName) throws Exception {
    	setupField(targetCtClass, fieldCtClass, fieldName,null);
    }
    public static void setupField(CtClass targetCtClass, CtClass fieldCtClass, String fieldName,Object defaultValue) throws Exception {
    	CtField successCtField  = createField(targetCtClass, fieldCtClass,"private", fieldName,defaultValue);
        createGetterAndSetter(targetCtClass, successCtField,"this." + fieldName + "=" + fieldName);
    }

    public static void setupStaticField(CtClass targetCtClass, CtClass fieldCtClass, String fieldName,Object defaultValue) throws Exception {
        createField(targetCtClass, fieldCtClass,"public static", fieldName,null);
    }

    public static CtField createField(CtClass targetCtClass, CtClass fieldCtClass,String signature, String fieldName,Object defaultValue) throws Exception {
        String fieldText=signature+" "+fieldCtClass.getName()+" "+fieldName+" ";
        if(defaultValue!=null && ClassPool.getDefault().get(String.class.getName())==fieldCtClass){
        	fieldText+="=\""+defaultValue+"\"";
        }else if(defaultValue!=null && fieldCtClass.isPrimitive()){
        	fieldText+="="+defaultValue;
        }else if(defaultValue!=null){
        	throw new RuntimeException("defaultValue only support string or primitive value");
        }
        fieldText+=";";
    	CtField successCtField  = CtField.make(fieldText, targetCtClass);
        targetCtClass.addField(successCtField);
        return successCtField;
    }
    

    public static void createGetterAndSetter(CtClass targetCtClass, CtField targetField,String setterMethod) throws Exception {
        String fieldName = targetField.getName();
        String fieldSetterName = BeanUtils.getSetterName(fieldName);
        String fieldGetterName = BeanUtils.getGetterName(fieldName, targetField.getType() == CtClass.booleanType);

        MethodUtils.addMethod(targetCtClass, "public void " + fieldSetterName + "(" + targetField.getType().getName() + " " + fieldName + "){" + setterMethod + ";}");
        MethodUtils.addMethod(targetCtClass, "public " + targetField.getType().getName() + " " + fieldGetterName + "(){return " + fieldName + ";}");
    }

}
